#ifndef _TASKQUEUE_H
#define _TASKQUEUE_H

#include <functional>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <iostream>

using std::cout;
using std::endl;
using std::mutex;
using std::condition_variable;
using std::queue;
using std::function;
using std::unique_lock;
using std::lock_guard;

using ElemType = function<void()>;

class TaskQueue{
private:
    size_t m_capacity;
    queue<ElemType> m_que;
    mutex m_mutex;
    condition_variable m_notEmpty;
    condition_variable m_notFull;
    bool m_flag = true;
public:
    TaskQueue(size_t capacity);

    ~TaskQueue();

    void push(ElemType &&value);

    ElemType pop();

    bool empty();

    bool full();

    void wakeup();

};

#endif //_TASKQUEUE_H